<template>
    <hot-table ref="hotTableRef" v-bind="$attrs" :data="dataList" :settings="hotSettings">
        <hot-column v-for="(colunm, index) in columnList" :key="index" :settings="colunm"> </hot-column>
    </hot-table>
</template>
<script>
import { HotColumn, HotTable } from '@handsontable/vue3';
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n';
import _ from 'lodash';
import { registerAllModules } from 'handsontable/registry';
import Handsontable from 'handsontable';
import { toRaw } from 'vue';

registerAllModules();
registerLanguageDictionary(zhCN);

export default {
    name: 'HotTablePlus',
    components: { HotTable, HotColumn },
    props: {
        columnList: {
            type: Array,
            default() {
                return [];
            },
        },
        dataList: {
            type: Array,
            default() {
                return [];
            },
        },
    },
    emits: ['selectSum'],
    data() {
        const negativeValueRenderer = (instance, td, row, col, prop, value, cellProperties) => {
            Handsontable.renderers.TextRenderer(instance, td, row, col, prop, value, cellProperties);
            const rowData = instance.getSourceDataAtRow(row);
            // console.log('rowData', row, col, prop, value, rowData);
            if (rowData['__color']) {
                td.style.color = rowData['__color'];
            }
        };
        Handsontable.renderers.registerRenderer('negativeValueRenderer', negativeValueRenderer);

        return {
            localData: [],
            selectSum: 0,
            hotSettings: {
                dropdownMenu: true,
                hiddenColumns: {
                    indicators: true,
                },
                colHeaders: true,
                // colWidths: [180, 220, 140, 120, 120, 120, 140],
                contextMenu: ['copy', '---------', 'row_above', 'row_below', 'remove_row'],
                themeName: 'ht-theme-main-dark-auto',
                language: zhCN.languageCode,
                autoColumnSize: { samplingRatio: 23 },
                multiColumnSorting: true,
                filters: true,
                rowHeaders: true,
                manualRowMove: true,
                headerClassName: 'htLeft',
                autoRowSize: true,
                autoWrapRow: true,
                autoWrapCol: true,
                manualRowResize: true,
                manualColumnResize: true,
                navigableHeaders: true,
                cells: (row, col) => {
                    return { renderer: 'negativeValueRenderer' };
                },
                licenseKey: 'non-commercial-and-evaluation',
            },
            // hotUpdateSettingFun: ,
        };
    },
    watch: {
        columnList: {
            handler: 'handleDataChange',
            immediate: true,
            deep: true,
        },
        dataList: {
            handler: 'handleDataChange',
            immediate: true,
            deep: true,
        },
        selectSum(val) {
            this.$emit('selectSum', val);
        },
    },
    mounted() {
        this.$refs.hotTableRef.hotInstance.addHook('afterSelectionEnd', () => {
            this.selectSum = this.calculateSum(this.$refs.hotTableRef.hotInstance);
        });
    },
    methods: {
        getHotData() {
            return this.$refs.hotTableRef.hotInstance.getSourceData();
        },
        hotSetData(data) {
            this.$refs.hotTableRef.hotInstance.updateSettings({ data: data }); // 更新数据源并重新渲染表格
        },
        hotAddDataAtRow(row, data) {
            let sourceData = this.$refs.hotTableRef.hotInstance.getSourceData();
            // 假设原始数据源是 data，并且你已经有了 Handsontable 的实例 hot
            let sourceDataClone = [...sourceData]; // 获取当前数据源的副本
            sourceDataClone.splice(row, 0, ...data); // 在第1行后面插入新数据
            this.$refs.hotTableRef.hotInstance.updateSettings({ data: sourceDataClone }); // 更新数据源并重新渲染表格
        },
        hotUpdateSettings() {
            console.log('hotUpdateSettings，执行了', +Date.now());
            if (this.$refs.hotTableRef) {
                this.$refs.hotTableRef.hotInstance.updateSettings({ columns: this.columnList });
                this.$refs.hotTableRef.hotInstance.updateSettings({ data: this.dataList });
            }
        },
        addHotContextMenu(name, callbackfn) {
            const currentMenuItems = toRaw(this.$refs.hotTableRef.hotInstance.getSettings().contextMenu);
            currentMenuItems.push({
                name: name,
                callback: (key, options) => {
                    callbackfn(key, options, this.$refs.hotTableRef.hotInstance);
                },
            });
            this.$refs.hotTableRef.hotInstance.updateSettings({
                contextMenu: currentMenuItems,
            });
        },
        handleDataChange: _.debounce(function () {
            this.hotUpdateSettings();
        }, 1000),
        calculateSum(hotInstance) {
            const selected = hotInstance.getSelected();
            if (selected && selected.length > 0) {
                let sum = 0;
                for (let i = 0; i < selected.length; i++) {
                    let selectedItem = selected[i];
                    // 开始必须小于结束
                    let rowGby = _.sortBy([selectedItem[0], selectedItem[2]]);
                    let colGby = _.sortBy([selectedItem[1], selectedItem[3]]);
                    let startRow = rowGby[0];
                    let endRow = rowGby[1];
                    let startCol = colGby[0];
                    let endCol = colGby[1];
                    for (let row = startRow; row <= endRow; row++) {
                        for (let col = startCol; col <= endCol; col++) {
                            const value = hotInstance.getDataAtCell(row, col);
                            if (typeof +value === 'number' || typeof value === 'number') {
                                sum += +value;
                            }
                        }
                    }
                }
                return sum;
            }
            return 0;
        },
    },
};
</script>

<style scoped></style>
